/*
 * Copyright (C) 2010 Leandro Aparecido <lehphyro@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.code.mjl.tracing.impl;

import java.lang.reflect.*;
import java.util.*;

import com.google.code.mjl.*;
import com.google.code.mjl.tracing.*;
import com.google.code.mjl.util.*;

public class TraceParserDefaultImpl implements TraceParser {

	public TracingParameters parse(Method method) {
		TracingParameters parameters;

		Map<String, Object> attributes = Annotations.getMergedAnnotationAttributes(method.getDeclaringClass(), Trace.class);
		if (attributes.isEmpty()) {
			attributes = Annotations.getMergedAnnotationAttributes(method, Trace.class);
			if (attributes.isEmpty()) {
				parameters = null;
			} else {
				parameters = new TracingParameters();
				parseAnnotation(attributes, parameters);
			}
		} else {
			parameters = new TracingParameters();
			parseAnnotation(attributes, parameters);

			attributes = Annotations.getMergedAnnotationAttributes(method, Trace.class);
			if (!attributes.isEmpty()) {
				parseAnnotation(attributes, parameters);
			}
		}

		return parameters;
	}

	@SuppressWarnings("unchecked")
	protected void parseAnnotation(Map<String, Object> attributes, TracingParameters parameters) {
		parameters.setEnabled((Boolean) attributes.get("enabled"));
		parameters.setLogGetMethods((Boolean) attributes.get("logGetMethods"));
		parameters.setLogSetMethods((Boolean) attributes.get("logSetMethods"));
		parameters.setLogObjectMethods((Boolean) attributes.get("logObjectMethods"));
		parameters.setLevel((Log.Level) attributes.get("level"));
		parameters.setAsync((Boolean) attributes.get("async"));

		String before = (String) attributes.get("before");
		if (!before.isEmpty()) {
			parameters.setBefore(before);
		}

		String after = (String) attributes.get("after");
		if (!after.isEmpty()) {
			parameters.setAfter(after);
		}

		Class<? extends Throwable>[] logFor = (Class<? extends Throwable>[]) attributes.get("logFor");
		for (Class<? extends Throwable> klass : logFor) {
			parameters.addLogFor(klass);
		}

		Class<? extends Throwable>[] noLogFor = (Class<? extends Throwable>[]) attributes.get("noLogFor");
		for (Class<? extends Throwable> klass : noLogFor) {
			parameters.addNoLogFor(klass);
		}
	}

}
